package com.zheng.study.web.shiro.credentials;

import com.zheng.study.base.service.redis.RedisService;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 登录的用户名匹配的校验在此处进行
 * 限定用户输入密码错误次数
 * ============================================================================
 * author : fallenpanda
 * createDate:  2018/8/17 。
 * ============================================================================
 */
public class LoginHashedCredentialsMatcher extends HashedCredentialsMatcher {

	private static final int MAX_RETRY_SECOND = 10*60;// 10分钟
	private static final int MAX_RETRY_COUNT = 5;// 10次

	private static final String SHIRO_PASSWORD_RETRY = "SHIRO_PASSWORD_RETRY_";

	@Autowired
	private RedisService redisService;

	@Override
	public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info){
		//登录账号
		String username = (String) token.getPrincipal();
		//缓存key
		String passwordRetryCache = SHIRO_PASSWORD_RETRY + username;

		//如果redis中存在此缓存记录
		if(redisService.exists(passwordRetryCache)){
			if(redisService.incr(passwordRetryCache) > MAX_RETRY_COUNT){
				throw new ExcessiveAttemptsException();
			}
		}else{
			redisService.set(passwordRetryCache, "1", MAX_RETRY_SECOND);
		}

		//校验凭证
		boolean matches = super.doCredentialsMatch(token, info);
		if(matches){
			//成功则重置失败次数
			redisService.set(passwordRetryCache, "1", MAX_RETRY_SECOND);
		}

		return matches;
	}

}
